path = require "path"
gm = require 'gm'
fs = require 'fs'
fsp = require '../libs/fs-promises'
_ = require 'underscore'
httpCacheControl = require '../libs/cache-header-control'


module.exports = (app) ->

  # handle image by default 640 * 640
  #  params:
  #   image: image file field
  #   x: crop start x
  #   y: crop start y
  #   w: crop width
  #   h: crop height
  #
  app.post '/api/apps/:app_id/images', app.uploader.single('image'), (req, res, next) ->
    console.log "上传图片: "
    if req.file.path
      gm_img = gm(req.file.path)
      dest_path = path.join app.get('sandbox_path'), req.app_id || req.params.app_id, 'images', req.file.originalname
      if req.body.crop # 截图功能实现
        crop = _.pick(req.body, ['x', 'y', 'w', 'h'])
        gm_img.crop(crop.w, crop.h, crop.x, crop.y)
      # 限制大小
      gm_img.resize 640, 640
      # 覆盖文件
      gm_img.write dest_path || req.file.path, (err) ->
        if err
          res.status(500).json(error: err)
        else
          res.status(200).json
            id: req.file.originalname
    else
      err = new Error 'please upload image and the key must use the \'image\' naming.'
      next(err)

  # fetch a image，support fs.
  # 参考gm API
  # 以x（乘号）为分割，左侧为宽，右侧为高
  # 单位可以是纯数字，代表像素。例如700，代表700像素
  # 也可以是数字加p结尾，代表百分比。例如75，代表75%，200，代表200%
  # 可以宽高参数同时提供，也可以只提供任意一个，如果只提供一个，则另一侧留空
  app.get '/api/apps/:app_id/images/:image_id', (req, res, next) ->
    # 设置无缓存 pm2 -> "args" : [ "noCache"]
    # if _.contains process.argv, 'noCache'
    #   httpCacheControl res
    # else
    #   httpCacheControl res, 'day' # 此图片1天缓存
    # TODO etag操作
    # TODO 防止 ../ ./ ../../
    # 去掉 id([^\s]*)支持文件结构：/images/xxx/xxx.jpg
    # 原因：当客户端有中文时浏览器会自动编码 /images/%E6%9C%BA%E6%A2%B0%E9%94%AE%E7%9B%98.jpg
    # 而express# req.params.id就会报错 Failed to decode param 'E6%9C%BA%E6%A2%B0%E9%94%AE%E7%9B%98.jpg'
    # 发现丢了一个%
    image_id = decodeURIComponent(req.params.image_id) # ajax中文浏览器编码问题fix
    dest_path = path.join app.get('sandbox_path'), req.app_id || req.params.app_id, "images", image_id
    # result: null or [all, width, height, options]
    resize = req.query.resize?.match /^(\d+p?)?x(\d+p?)?([%@!\<\>])?$/
    rotate = req.query.rotate?.match /^(\d+)$/

    file_path = dest_path || path.resolve((require "os").tmpdir(), image_id)
    fs.exists file_path, (exists) ->
      if exists
        gm_img = gm(file_path)
        gm_img = gm_img.resize(resize[1], resize[2], resize[3]) if resize
        gm_img = gm_img.rotate('black', rotate[1]) if rotate
        gm_img.size (err, size) ->
          # 将size写在响应头，目前未应用
          res.set width: size.width, height: size.height
          # 流输出
          gm_img.stream (err, stdout, stderr) -> stdout.pipe(res)
      else
        res.status(404).send(error: 'image not found.')


  # 显示当前app下所有图片
  app.get '/api/apps/:app_id/images', (req, res, next) ->
    dest_path = path.join app.get('sandbox_path'), req.app_id || req.params.app_id, 'images'
    try
      fsp.traverse_safe dest_path, relative: true
      .then (imgs) ->
        imgs = imgs.map (each) ->
          id: each
        res.status(200).json(imgs)
    catch error
      next(error)


  # 删除当前app下某个图片
  app.delete '/api/apps/:app_id/images/:image_id', (req, res, next) ->
    image_id = decodeURIComponent(req.params.image_id) # ajax中文浏览器编码问题fix
    dest_path = path.join app.get('sandbox_path'), req.app_id || req.params.app_id, 'images', image_id
    try
      fsp.remove_safe dest_path
      .then (err) ->
        return next(err) if err
        res.status(200).json({message: 'delete this image successfully.'})
    catch error
      next(error)
